package com.ld.hpfs.web.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ld.hpfs.common.jackson.JackJson;
import com.ld.hpfs.common.springmvc.DateConvertEditor;
import com.ld.hpfs.common.utils.Tools;
import com.ld.hpfs.common.utils.RsaDecrypt;
import com.ld.hpfs.pojo.Criteria;
import com.ld.hpfs.pojo.ExceptionReturn;
import com.ld.hpfs.pojo.ExtReturn;
import com.ld.hpfs.pojo.User;
import com.ld.hpfs.service.LeftService;
import com.ld.hpfs.service.UserService;
import com.ld.hpfs.web.interseptor.WebConstants;

/**
 * 用户登录相关
 * 
 * @author bole
 * @date 2012-08-18 22:00:00
 */
@Controller
public class LoginController {

	private static final Logger logger = LoggerFactory.getLogger(LoginController.class);
	private static final String param = null;
	
	@Autowired
	private LeftService leftService;
	
	@Autowired
	private UserService userService;
	/** 限制时间 */
	@Value("${limit.millis:3600000}")
	private Long millis;

	@SuppressWarnings("unused")
	@Autowired
	private MessageSource messageSource;

	@InitBinder
	public void initBinder(WebDataBinder binder) {
		binder.registerCustomEditor(Date.class, new DateConvertEditor());
		binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
	}

	/**
	 * 退出登录
	 */
	@RequestMapping("/logout")
	@ResponseBody
	public Object logout(HttpSession session, Locale locale) {
		try {
			session.removeAttribute(WebConstants.CURRENT_USER);
			session.invalidate();
			return new ExtReturn(true, "退出系统成功！");			
		} catch (Exception e) {
			logger.error("Exception: ", e);
			return new ExceptionReturn(e);
		}
	}

	/**
	 * 用户菜单treeMenu的数据
	 * 
	 * @throws IOException
	 */
	@RequestMapping("/treeMenu")
	@ResponseBody
	public Object treeMenu(HttpSession session, HttpServletResponse response) {
		return null;
	}

	/**
	 * 用户登录
	 */
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	@ResponseBody
	public Object login(@RequestParam String account, @RequestParam String password,@RequestParam String company,@RequestParam String lang
				, HttpSession session, HttpServletRequest request) {
		try {
			if (StringUtils.isBlank(account)) {
				return new ExtReturn(false, "帐号不能为空！");
			}
			if (StringUtils.isBlank(password)) {
				return new ExtReturn(false, "密码不能为空！");
			}
			Criteria criteria = new Criteria();
			criteria.put("account", account);
			criteria.put("passwordIn", password);
			criteria.put("loginip", this.getIpAddr(request));
			String result = this.userService.selectByBaseUser(criteria);
			
			HashMap<String,Object> temp = new HashMap<String,Object>();										
			temp.put("login_ip",this.getIpAddr(request));
			temp.put("account", account);
			
			if ("01".equals(result)) {
				User baseUser = (User) criteria.get("baseUser");
				session.setAttribute(WebConstants.CURRENT_USER, baseUser);
				HashMap<String,Object> param = new HashMap<String,Object>();
				param.put("company", company);
				param.put("user_id", baseUser.getUserId());
				HashMap<String,Object> check = userService.getCompanyId(param);
				if(check!=null){
					RsaDecrypt RSA = new RsaDecrypt();
					temp.put("company", company);
					temp.put("login_result", "success");
					userService.insertLoginInfo(temp);
					session.setAttribute(WebConstants.CURRENT_LANG, lang);
					session.setAttribute(WebConstants.CURRENT_COMPANY,check.get("id"));
					session.setAttribute(WebConstants.MAX_COMPANY_NUMBER,RSA.Company_Number());  //公司数量获取
					session.setAttribute(WebConstants.MAX_USER_NUMBER,RSA.User_Number());   //用户数量获取
					long Login = RSA.LoginTime();  //判断登陆证书是否过期
					if(Login == -1){
  						session.removeAttribute(WebConstants.CURRENT_USER);
						return new ExtReturn(false, "您的证书已过期，禁止登陆!");  //禁止登陆
 					}else if(Login == -2){
 						session.removeAttribute(WebConstants.CURRENT_USER);
						return new ExtReturn(false, "您的证书不存在，禁止登陆!");  //禁止登陆
 					}else if(Login == -3){
 						session.removeAttribute(WebConstants.CURRENT_USER);
						return new ExtReturn(false, "您的证书存在错误，禁止登陆!");  //禁止登陆
 					}else if(Login == -4){
 						session.removeAttribute(WebConstants.CURRENT_USER);
						return new ExtReturn(false, "您的证书版本错误，禁止登陆!");  //禁止登陆
 					}
 					return new ExtReturn(true, "success",Login);    //可以登录,Login为可登陆天数
				} else {
					temp.put("company", company);
					temp.put("login_result", "failure:用户无此公司权限!");
					userService.insertLoginInfo(temp);
					session.removeAttribute(WebConstants.CURRENT_USER);
					return new ExtReturn(false, "用户无此公司权限!");
				}
			} else if ("00".equals(result)) {
				temp.put("company", company);
				temp.put("login_result", "failure:用户名或者密码错误!");
				userService.insertLoginInfo(temp);
				return new ExtReturn(false, "用户名或者密码错误!");
			}else {
				return new ExtReturn(false, result);
			}
		} catch (Exception e) {
			logger.error("Exception: ", e);
			return new ExceptionReturn(e);
		}
	}

	
	
	/**
	 * 取得客户端真实ip
	 * 
	 * @param request
	 * @return 客户端真实ip
	 */
	public String getIpAddr(HttpServletRequest request) {
		String ip = request.getHeader("X-Forwarded-For");
		logger.debug("1- X-Forwarded-For ip={}", ip);
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
			logger.debug("2- Proxy-Client-IP ip={}", ip);
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
			logger.debug("3- WL-Proxy-Client-IP ip={}", ip);
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_CLIENT_IP");
			logger.debug("4- HTTP_CLIENT_IP ip={}", ip);
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_X_FORWARDED_FOR");
			logger.debug("5- HTTP_X_FORWARDED_FOR ip={}", ip);
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
			logger.debug("6- getRemoteAddr ip={}", ip);
		}
		logger.info("finally ip={}", ip);
		return ip;
	}

	/**
	 * 转到找回用户密码页面
	 */
	@RequestMapping(value = "/findpwd", method = RequestMethod.GET)
	public String findpwd() {
		return "user/findpwd";
	}

	/**
	 * 找回用户密码
	 */
	@RequestMapping(value = "/findpwd", method = RequestMethod.POST)
	@ResponseBody
	public Object saveFindpwd(User user,@RequestParam String captcha,HttpSession session) {
		return null;
	}

	/**
	 * 找回用户密码时的重新设置密码的页面
	 */
	@RequestMapping(value = "/resetpwd/{token}/{userId}", method = RequestMethod.GET)
	public String resetpwd(@PathVariable String token, @PathVariable String userId, Model model) {
		User user = this.userService.selectByPrimaryKey(userId);
		if (user == null || !user.getPassword().equals(token.toLowerCase()) || compareTo(user.getLastLoginTime())) {
			model.addAttribute("error", "链接已经失效！");
			return "user/resetpwd";
		}
		model.addAttribute("t", token);
		model.addAttribute("u", userId);
		return "user/resetpwd";
	}

	/**
	 * 找回用户密码时的重新设置密码的页面
	 */
	@RequestMapping(value = "/resetpwd", method = RequestMethod.POST)
	public String resetpwdSave(@RequestParam String u, @RequestParam String t, @RequestParam String newpwd, @RequestParam String renewpwd,
			Model model) {
		try {
			model.addAttribute("t", t);
			model.addAttribute("u", u);
			if (StringUtils.isBlank(u)) {
				model.addAttribute("msg", "密码修改失败！");
				return "user/resetpwd";
			}
			if (StringUtils.isBlank(t)) {
				model.addAttribute("msg", "密码修改失败！");
				return "user/resetpwd";
			}
			if (StringUtils.isBlank(newpwd)) {
				model.addAttribute("msg", "新密码不能为空！");
				return "user/resetpwd";
			}
			if (StringUtils.isBlank(renewpwd)) {
				model.addAttribute("msg", "确认密码不能为空！");
				return "user/resetpwd";
			}
			if (!renewpwd.equals(newpwd)) {
				model.addAttribute("msg", "新密码和确认密码输入不一致！");
				return "user/resetpwd";
			}
			Criteria criteria = new Criteria();
			criteria.put("token", t);
			criteria.put("userId", u);
			criteria.put("password", newpwd);
			String result = this.userService.updatePassword(criteria);
			if ("01".equals(result)) {
				model.addAttribute("msg", "密码修改成功！请重新登录");
			} else if ("00".equals(result)) {
				model.addAttribute("msg", "密码修改失败！");
			} else {
				model.addAttribute("msg", result);
			}
		} catch (Exception e) {
			logger.error("Exception: ", e);
			model.addAttribute("msg", e.getMessage());
		}
		return "user/resetpwd";
	}

	/**
	 * 得到用户的公司信息
	 * @param user
	 * @return
	 */
	@RequestMapping(value = "/getCompany", method = RequestMethod.POST)
	public void getCompany(@RequestParam String user_name
			, HttpSession session, HttpServletRequest request,HttpServletResponse response,PrintWriter writer){
		HashMap<String,Object> param = new HashMap<String,Object>();
		response.setContentType("text/plain;charset=UTF-8");
		try {
			User user = (User) session.getAttribute(WebConstants.CURRENT_USER);
			if(Tools.isEmpty(user_name)){
				writer.print("");
			}else{
				if (Tools.isEmpty(user_name)) {
					param.put("user_name", user.getAccount());
				} else {
					param.put("user_name", user_name);
				}
				
				ArrayList<HashMap<String,Object>> result = userService.getCompany(param);
				String returnMsg = JackJson.fromObjectToJson(result);
				logger.debug("{}", returnMsg);
				writer.print(returnMsg);
			}	
		} catch (Exception e) {
			logger.error("Exception: ", e);
		} finally {
			writer.flush();
			writer.close();
		}
	}
	
	@RequestMapping(value = "/getUserState" )
	public void getUserState(@RequestParam String account
			, HttpSession session, HttpServletRequest request,HttpServletResponse response,PrintWriter writer){
		HashMap<String,Object> param = new HashMap<String,Object>();
		HashMap<String,Object> result = new HashMap<String,Object>();
		response.setContentType("text/plain;charset=UTF-8");
		try {
			param.put("account", account);
			HashMap<String,Object> check = userService.getUserId(param);
			if(check == null){	
				result.put("resultcode",0);
			}else{
				String ret = userService.getUserState(param);								
				if(ret.equals("0") || ret == null){
					result.put("resultcode",0);
				}else if(ret.equals("1")){
					result.put("resultcode",9);
				}
			}
				String returnMsg = JackJson.fromObjectToJson(result);
				logger.debug("{}", returnMsg);
				writer.print(returnMsg);
			
		} catch (Exception e) {
	 		logger.error("Exception: ", e);
	 	} finally {
	 		writer.flush();
	 		writer.close();
	 	}
	}
	
	/**
	 * 日期比较
	 * 
	 * @param date
	 * @return
	 */
	private boolean compareTo(Date date) {
		Calendar c = Calendar.getInstance();
		long now = c.getTimeInMillis();
		c.setTime(date);
		long lastly = c.getTimeInMillis();
		// 60分钟1000*60*60;
		return (now - lastly) >= millis;
	}
	
	private String formatResults(ArrayList<HashMap<String,Object>> result)
    {
        StringBuffer sb = new StringBuffer();
        sb.append("[");
        if (result != null)
        {
            for (int i = 0; i < result.size(); i++)
            {
            	HashMap<String,Object> account = result.get(i);
                String code = account.get("code").toString();
                String title = account.get("title").toString();

                sb.append("{'code':'").append(code).append("',").append("'title':'").append(title).append("'").append("}");

                if (i < result.size() - 1)
                {
                    sb.append(",");
                }
            }
        }
        sb.append("]");
        try
        {
            return sb.toString();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return "";
    }
	
	
	@RequestMapping(value = "/geteditioninfo" )
	public void geteditioninfo(HttpSession session, HttpServletRequest request,HttpServletResponse response,PrintWriter writer){
		HashMap<String,Object> result = new HashMap<String,Object>();
		response.setContentType("text/plain;charset=UTF-8");
		try {
			RsaDecrypt res=new RsaDecrypt();
			String maxcustomer=res.User_Number();
			String maxcompany=res.Company_Number();
			String expired=res.getTime();
			String customer=res.getCustomer();
			result.put("maxcustomer", maxcustomer);
			result.put("maxcompany", maxcompany);
			result.put("expired", expired);
			result.put("customer", customer);
			String returnMsg = JackJson.fromObjectToJson(result);
			logger.debug("{}", returnMsg);
			writer.print(returnMsg);
			
		} catch (Exception e) {
	 		logger.error("Exception: ", e);
	 	} finally {
	 		writer.flush();
	 		writer.close();
	 	}
	}
	
}
